﻿using System;
using System.Diagnostics;
using System.Reflection;
using CodeLibrary.Reflection.Delegate;
using CodeLibrary.Reflection.Emit;
using CodeLibrary.Reflection.ExpressionTree;

namespace CodeLibrary.Reflection
{
    class ReflectionTest
    {
        public int TestData { get; set; }

        public static void test()
        {
            Console.WriteLine(System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion());

            int count = 1000000;

            //ReflectionTest testObj = new ReflectionTest();
            //PropertyInfo propInfo = typeof(ReflectionTest).GetProperty("OrderID");

            //Console.Write("直接访问花费时间：       ");
            //Stopwatch watch1 = Stopwatch.StartNew();

            //for (int i = 0; i < count; i++)
            //    testObj.TestData = 123;

            //watch1.Stop();
            //Console.WriteLine(watch1.Elapsed.ToString());


            //SetValueDelegate setter2 = DynamicMethodFactory.CreatePropertySetter(propInfo);
            //Console.Write("EmitSet花费时间：        ");
            //Stopwatch watch2 = Stopwatch.StartNew();

            //for (int i = 0; i < count; i++)
            //    setter2(testObj, 123);

            //watch2.Stop();
            //Console.WriteLine(watch2.Elapsed.ToString());


            //Console.Write("纯反射花费时间：　       ");
            //Stopwatch watch3 = Stopwatch.StartNew();

            //for (int i = 0; i < count; i++)
            //    propInfo.SetValue(testObj, 123, null);

            //watch3.Stop();
            //Console.WriteLine(watch3.Elapsed.ToString());

            //Console.Write("泛型委托花费时间：       ");
            //SetterWrapper<ReflectionTest, int> setter3 = new SetterWrapper<ReflectionTest, int>(propInfo);
            //Stopwatch watch4 = Stopwatch.StartNew();

            //for (int i = 0; i < count; i++)
            //    setter3.SetValue(testObj, 123);

            //watch4.Stop();
            //Console.WriteLine(watch4.Elapsed.ToString());


            //Console.Write("通用接口花费时间：       ");
            //ISetValue setter4 = GetterSetterFactory.CreatePropertySetterWrapper(propInfo);
            //Stopwatch watch5 = Stopwatch.StartNew();

            //for (int i = 0; i < count; i++)
            //    setter4.Set(testObj, 123);

            //watch5.Stop();
            //Console.WriteLine(watch5.Elapsed.ToString());


            MethodInfo methodInfo = typeof(ReflectionTest).GetMethod("Call");
            DynamicMethodExecutor executor = new DynamicMethodExecutor(methodInfo);
            Stopwatch watch3 = Stopwatch.StartNew();
            watch3.Start();
            Program program = new Program();
            object[] parameters = new object[] { new object(), new object(), new object() };
            for (int i = 0; i < count; i++)
            {
                executor.Execute(program, parameters);
            }
            watch3.Stop();
            Console.WriteLine(watch3.Elapsed + " (Dynamic executor)");
        }

        public void Call(object o1, object o2, object o3) { }

    }
}
